lib: Add an API to construct a `MutableTree` from a commit
authorColin Walters <walters@verbum.org>
Thu, 30 Sep 2021 17:21:15 +0000 (13:21 -0400)
committerColin Walters <walters@verbum.org>
Fri, 1 Oct 2021 13:34:19 +0000 (09:34 -0400)
This is nicer than having the caller parse the commit
object, or indirect via the `OstreeRepoFile*` object of the root.

Will be used in ostree-rs-ext around tar parsing.

apidoc/ostree-sections.txt
src/libostree/libostree-devel.sym
src/libostree/ostree-mutable-tree.c
src/libostree/ostree-mutable-tree.h
src/ostree/ot-builtin-commit.c

index ae8abe81aea035e10bb119ba772eef82bd0a8ae6..aa74c839b8a12f701b89945a79d8b41aa4364e13 100644 (file)
@@ -268,6 +268,7 @@ OstreeLzmaDecompressorClass
 <FILE>ostree-mutable-tree</FILE>
 OstreeMutableTree
 ostree_mutable_tree_new
+ostree_mutable_tree_new_from_commit
 ostree_mutable_tree_new_from_checksum
 ostree_mutable_tree_check_error
 ostree_mutable_tree_set_metadata_checksum
index 35d539567801f04a78cfcbfeb805adc4cde74409..6b6b5c6c98e335f6e1a3368c586c15cd1b7e35c9 100644 (file)
@@ -25,6 +25,7 @@
 LIBOSTREE_2021.5 {
 global:
   ostree_sepolicy_new_from_commit;
+  ostree_mutable_tree_new_from_commit;
 } LIBOSTREE_2021.4;
 
 /* Stub section for the stable release *after* this development one; don't
index 8509d1566d6b75d65ff5e2faef58ab742f3969e5..bba3cf915374aeeb9acedb0e8afbe6f6272f8dc5 100644 (file)
@@ -681,3 +681,39 @@ ostree_mutable_tree_new_from_checksum (OstreeRepo *repo,
   out->metadata_checksum = g_strdup (metadata_checksum);
   return out;
 }
+
+/**
+ * ostree_mutable_tree_new_from_commit:
+ * @repo: The repo which contains the objects refered by the checksums.
+ * @rev: ref or SHA-256 checksum
+ *
+ * Creates a new OstreeMutableTree with the contents taken from the given commit.
+ * The data will be loaded from the repo lazily as needed.
+ *
+ * Returns: (transfer full): A new tree
+ * Since: 2021.5
+ */
+OstreeMutableTree *
+ostree_mutable_tree_new_from_commit (OstreeRepo *repo,
+                                     const char *rev,
+                                     GError    **error)
+{
+  g_autofree char *commit = NULL;
+  if (!ostree_repo_resolve_rev (repo, rev, FALSE, &commit, error))
+    return NULL;
+  g_autoptr(GVariant) commit_v = NULL;
+  if (!ostree_repo_load_commit (repo, commit, &commit_v, NULL, error))
+    return NULL;
+
+  g_autoptr(GVariant) contents_checksum_v = NULL;
+  g_autoptr(GVariant) metadata_checksum_v = NULL;
+  char contents_checksum[OSTREE_SHA256_STRING_LEN + 1];
+  char metadata_checksum[OSTREE_SHA256_STRING_LEN + 1];
+  g_variant_get_child (commit_v, 6, "@ay", &contents_checksum_v);
+  ostree_checksum_inplace_from_bytes (g_variant_get_data (contents_checksum_v),
+                                      contents_checksum);
+  g_variant_get_child (commit_v, 7, "@ay", &metadata_checksum_v);
+  ostree_checksum_inplace_from_bytes (g_variant_get_data (metadata_checksum_v),
+                                      metadata_checksum);
+  return ostree_mutable_tree_new_from_checksum (repo, contents_checksum, metadata_checksum);
+}
index 753f96e7f04b652da944104a101cfb9ff4b2d248..9bf368025f67e37baaaddc91d58922ed7e01f8af 100644 (file)
@@ -52,6 +52,12 @@ GType   ostree_mutable_tree_get_type (void) G_GNUC_CONST;
 _OSTREE_PUBLIC
 OstreeMutableTree *ostree_mutable_tree_new (void);
 
+_OSTREE_PUBLIC
+OstreeMutableTree *
+ostree_mutable_tree_new_from_commit (OstreeRepo *repo,
+                                     const char *rev,
+                                     GError    **error);
+
 _OSTREE_PUBLIC
 OstreeMutableTree * ostree_mutable_tree_new_from_checksum (OstreeRepo *repo,
                                                            const char *contents_checksum,
index b993678e7ebeac27ab42d34d81fc709b4a8748d7..a306c114bc6a6b679855c47b41329a48e9503c35 100644 (file)
@@ -638,20 +638,14 @@ ostree_builtin_commit (int argc, char **argv, OstreeCommandInvocation *invocatio
 
   if (opt_base)
     {
-      g_autofree char *base_commit = NULL;
-      g_autoptr(GFile) base_root = NULL;
-      if (!ostree_repo_read_commit (repo, opt_base, &base_root, &base_commit, cancellable, error))
+      mtree = ostree_mutable_tree_new_from_commit (repo, opt_base, error);
+      if (!mtree)
         goto out;
-      OstreeRepoFile *rootf = (OstreeRepoFile*) base_root;
-
-      mtree = ostree_mutable_tree_new_from_checksum (repo,
-                                                     ostree_repo_file_tree_get_contents_checksum (rootf),
-                                                     ostree_repo_file_tree_get_metadata_checksum (rootf));
 
       if (opt_selinux_policy_from_base)
         {
           g_assert (modifier);
-          if (!ostree_repo_commit_modifier_set_sepolicy_from_commit (modifier, repo, base_commit, cancellable, error))
+          if (!ostree_repo_commit_modifier_set_sepolicy_from_commit (modifier, repo, opt_base, cancellable, error))
             goto out;
           /* Don't try to handle it twice */
           opt_selinux_policy_from_base = FALSE;